What tweets got the most attention. frequency of tweets posted on a topic

library(rtweet)
library(ggplot2)
library(tidyr)
library(dplyr)

Attaching package: 㤼㸱dplyr㤼㸲

The following objects are masked from 㤼㸱package:stats㤼㸲:

    filter, lag

The following objects are masked from 㤼㸱package:base㤼㸲:

    intersect, setdiff, setequal, union
library(tidytext)
library(stringr)
library(scales)
library(readr)

Attaching package: 㤼㸱readr㤼㸲

The following object is masked from 㤼㸱package:scales㤼㸲:

    col_factor
library(lubridate)

Attaching package: 㤼㸱lubridate㤼㸲

The following objects are masked from 㤼㸱package:base㤼㸲:

    date, intersect, setdiff, union
library(vader)
library(topicmodels)
library(quanteda)
Package version: 3.0.0
Unicode version: 13.0
ICU version: 69.1
Parallel computing: 8 of 8 threads used.
See https://quanteda.io for tutorials and examples.
library(lubridate)
library(zoo)

Attaching package: 㤼㸱zoo㤼㸲

The following object is masked from 㤼㸱package:quanteda㤼㸲:

    index

The following objects are masked from 㤼㸱package:base㤼㸲:

    as.Date, as.Date.numeric
library(plotly)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio

Attaching package: 㤼㸱plotly㤼㸲

The following object is masked from 㤼㸱package:ggplot2㤼㸲:

    last_plot

The following object is masked from 㤼㸱package:stats㤼㸲:

    filter

The following object is masked from 㤼㸱package:graphics㤼㸲:

    layout
library(forcats)
library(igraph)

Attaching package: 㤼㸱igraph㤼㸲

The following object is masked from 㤼㸱package:plotly㤼㸲:

    groups

The following objects are masked from 㤼㸱package:lubridate㤼㸲:

    %--%, union

The following objects are masked from 㤼㸱package:dplyr㤼㸲:

    as_data_frame, groups, union

The following object is masked from 㤼㸱package:tidyr㤼㸲:

    crossing

The following objects are masked from 㤼㸱package:stats㤼㸲:

    decompose, spectrum

The following object is masked from 㤼㸱package:base㤼㸲:

    union
library(ggraph)
library(widyr)
library(qdapRegex)

Attaching package: 㤼㸱qdapRegex㤼㸲

The following object is masked from 㤼㸱package:dplyr㤼㸲:

    explain

The following object is masked from 㤼㸱package:ggplot2㤼㸲:

    %+%
origop <- options("httr_oauth_cache")
options(httr_oauth_cache = TRUE)

api_key <- "5PgtS7ljq5ZbBoXnemU5qHe62"
api_secret <- "M44LeduQ4zoyDxQIkAFjeIJrpDhWnb5xASDvhahTlrAvOhN7fx"
access_token <- "743029724750942208-JLEp26XrjwvQ1CPJUXwvdUMLka82cgx"
access_secret <- "XRMeMBaOgQy2BC1Bd9iJARfMIyK40VKyII1ZRcf9nS0qd"
token <- create_token(
  app = "KyleResearchApp",
  consumer_key = api_key,
  consumer_secret = api_secret,
  access_token = access_token,
  access_secret = access_secret
)
media_agency_df <- read_csv("data_in/media_agency_tweets.csv")

-- Column specification -----------------------------------------------------------------------------------------------------------
cols(
  .default = col_character(),
  created_at = col_datetime(format = ""),
  display_text_width = col_double(),
  reply_to_status_id = col_logical(),
  reply_to_user_id = col_logical(),
  reply_to_screen_name = col_logical(),
  is_quote = col_logical(),
  is_retweet = col_logical(),
  favorite_count = col_double(),
  retweet_count = col_double(),
  quote_count = col_logical(),
  reply_count = col_logical(),
  symbols = col_logical(),
  ext_media_type = col_logical(),
  quoted_status_id = col_logical(),
  quoted_text = col_logical(),
  quoted_created_at = col_logical(),
  quoted_source = col_logical(),
  quoted_favorite_count = col_logical(),
  quoted_retweet_count = col_logical(),
  quoted_user_id = col_logical()
  # ... with 30 more columns
)
i Use `spec()` for the full column specifications.

207 parsing failures.
 row                  col           expected               actual                              file
2282 reply_to_status_id   1/0/T/F/TRUE/FALSE x1405793506459783168 'data_in/media_agency_tweets.csv'
2282 reply_to_user_id     1/0/T/F/TRUE/FALSE x1358665806121467908 'data_in/media_agency_tweets.csv'
2282 reply_to_screen_name 1/0/T/F/TRUE/FALSE LA89db               'data_in/media_agency_tweets.csv'
3687 reply_to_user_id     1/0/T/F/TRUE/FALSE x240546747           'data_in/media_agency_tweets.csv'
3687 reply_to_screen_name 1/0/T/F/TRUE/FALSE MasegoRahlaga        'data_in/media_agency_tweets.csv'
.... .................... .................. .................... .................................
See problems(...) for more details.

Comparing Tweet Archives

Some tweets fetched date further back. The 3200 tweet pull per user causes this. It tells us that agencies like News24 and SABC News Tweet more daily than Daily Maverick.

ggplot(media_agency_df, aes(x = created_at, fill = screen_name)) +
  geom_histogram(position = "identity", bins = 20, show.legend = FALSE) +
  facet_wrap(~screen_name, ncol = 1)

We first clean the original text to remove links, punctuation, digits, links, @’s. Then we tokenize the Tweets and remove stop words from tidytext and our own stopword dictionary. We also use the “twitter” token to handle any left over @’s and URLS.

#tidy df and unnest
tidy_media_df <- media_agency_df %>% 
  #filter(str_detect(text, fixed(covid_dictionary, ignore_case = TRUE))) %>%
  unnest_tokens(word, text, token = "tweets") %>% 
  filter(!word %in% stop_words$word,
         !word %in% agency_stop_words$word,
        # !word %in% negated_words$word2,
         !word %in% str_remove_all(stop_words$word, "'"),
         str_detect(word, "[a-z]"))
Using `to_lower = TRUE` with `token = 'tweets'` may not preserve URLs.

From our tidyed Tweet dataset, we look for the top words that appear. This will give us a good idea of what topics are being discussed the most. We find that COVID-19 has been the main topic of discussion. President appears second as President Ramaphosa of South Africa usually adresses the nation regarding COVID-19 information. Additionally, Zuma also appears as he is mentioned as “former president Zuma” in most articles. Zuma appears more as his recent court avoidance and sentencing is being Tweeted. General words surrounding the COVID-19 topic as it is still the main pressure on the country, espicially involving Gauteng’s rise in infections.

#top words
top_words <- tidy_media_df %>% 
  anti_join(stop_words) %>% 
  count(word) %>% 
  arrange(desc(n))
top_words %>%
  slice(1:20) %>%
  ggplot(aes(reorder(word, -n), n, fill = word)) +
  geom_bar(stat="identity") +
  theme_minimal() +
  theme(
    axis.text.x = element_text(angle = 60, hjust = 1, size = 13),
    plot.title = element_text(hjust = 0.5, size = 18)
    ) +
  ylab("Frequency") +
  xlab ("") +
  ggtitle("Most frequent media agency tweets") +
  guides(fill=FALSE)

News

#tf-idf
tidy_media_tf_idf <- tidy_media_df %>% 
  select(screen_name, word) %>% 
  count(word, screen_name) %>% 
  bind_tf_idf(word, screen_name, n) 

#calculate a frequency for each agency and word
frequency <- tidy_media_tf_idf %>% 
  group_by(screen_name) %>% 
  count(word, sort = TRUE) %>% 
  left_join(tidy_media_df %>% 
              group_by(screen_name) %>% 
              summarise(total = n())) %>%
  mutate(freq = n/total)
Joining, by = "screen_name"
tidy_media_tf_idf %>% filter(word == "iss")
tidy_media_df %>% filter(word == "iss")

tidy_media_tf_idf %>%
  group_by(screen_name) %>%
  slice_max(tf_idf, n = 15) %>%
  ungroup() %>%
  ggplot(aes(tf_idf, fct_reorder(word, tf_idf), fill = screen_name)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(~screen_name, ncol = 2, scales = "free") +
  labs(x = "tf-idf", y = NULL)

By modelling bigrams and trigrams for our dataset gives us a better understanding of what topic is being discussed with each word. We can then also see which sentiments are incorrectly labeled. “not good” gives better context of a negative sentiment, rather than it being incorrectly identified as positive good.

We give more weight to words that appear more often with the incorrect sentiment. We can now reverse the sentiment of these words once VADER has been run on the dataset.

Trigrams were modelled but were not necessary as bigrams provided enough information

#trigrams
tidy_trigram_df <- media_agency_df %>%
  filter(!str_detect(text, "^RT")) %>%
  mutate(text = gsub(" ?(f|ht)tp(s?)://(.*)[.][a-z]+", " ", text)) %>%
  unnest_tokens(trigram, text, token = "ngrams", n = 3) %>%
  separate(trigram, c("word1", "word2", "word3"), sep = " ")

trigrams_filtered <- trigrams_separated %>%
  filter(!word1 %in% stop_words$word) %>%
  filter(!word2 %in% stop_words$word) %>% 
  filter(!word3 %in% stop_words$word) 

# new trigrams counts:
trigram_counts <- trigrams_filtered %>% 
  count(word1, word2, word3, sort = TRUE)

trigrams_united <- trigrams_filtered %>%
  unite(trigram, word1, word2, word3, sep = " ")

#tf-idf trigrams
tidy_trigram_df <- trigrams_united %>%
  count(screen_name, trigram) %>%
  bind_tf_idf(trigram, screen_name, n) %>%
  arrange(desc(tf_idf))

tidy_trigram_df %>%
  group_by(screen_name) %>%
  slice_max(tf_idf, n = 10) %>%
  ungroup() %>%
  ggplot(aes(tf_idf, fct_reorder(trigram, tf_idf), fill = screen_name)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(~screen_name, ncol = 2, scales = "free") +
  labs(x = "tf-idf", y = NULL)

#sentiment
ggplotly(ggplot(data=media_vader_df, aes(x=created_at)) +
  geom_line(aes(y=rollmean(compound, k=30, na.pad = TRUE)), color="pink", size=.5)+
  geom_smooth(aes(y=compound)) +
  theme_minimal()+
  facet_wrap(~screen_name) +
  scale_y_continuous(expand = c(0,0)))
`geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
Removed 979 rows containing non-finite values (stat_smooth).

install.packages("ldatuning")
WARNING: Rtools is required to build R packages but is not currently installed. Please download and install the appropriate version of Rtools before proceeding:

https://cran.rstudio.com/bin/windows/Rtools/
Installing package into 㤼㸱C:/Users/Administrator/Documents/R/win-library/4.0㤼㸲
(as 㤼㸱lib㤼㸲 is unspecified)
trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.0/ldatuning_1.0.2.zip'
Content type 'application/zip' length 541109 bytes (528 KB)
downloaded 528 KB
package ‘ldatuning’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
    C:\Users\Administrator\AppData\Local\Temp\RtmpQZiRta\downloaded_packages
install.packages("devtools")
Error in install.packages : Updating loaded packages
devtools::install_github("nikita-moor/ldatuning")
WARNING: Rtools is required to build R packages, but is not currently installed.

Please download and install Rtools 4.0 from https://cran.r-project.org/bin/windows/Rtools/.
Downloading GitHub repo nikita-moor/ldatuning@HEAD
These packages have more recent versions available.
It is recommended to update all of them.
Which would you like to update?

1: All                               
2: CRAN packages only                
3: None                              
4: colorspace (2.0-1 -> 2.0-2) [CRAN]
5: Rcpp       (1.0.6 -> 1.0.7) [CRAN]
6: cli        (2.5.0 -> 3.0.0) [CRAN]
install.packages("devtools")
1
colorspace (2.0-1 -> 2.0-2) [CRAN]
Rcpp       (1.0.6 -> 1.0.7) [CRAN]
cli        (2.5.0 -> 3.0.0) [CRAN]
Installing 3 packages: colorspace, Rcpp, cli
Installing packages into 㤼㸱C:/Users/Administrator/Documents/R/win-library/4.0㤼㸲
(as 㤼㸱lib㤼㸲 is unspecified)

  There is a binary version available but the source version is later:

  Binaries will be installed
trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.0/colorspace_2.0-2.zip'
Content type 'application/zip' length 2649327 bytes (2.5 MB)
downloaded 2.5 MB

trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.0/Rcpp_1.0.6.zip'
Content type 'application/zip' length 3253582 bytes (3.1 MB)
downloaded 3.1 MB

trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.0/cli_3.0.0.zip'
Content type 'application/zip' length 756454 bytes (738 KB)
downloaded 738 KB
package ‘colorspace’ successfully unpacked and MD5 sums checked
cannot remove prior installation of package 㤼㸱colorspace㤼㸲problem copying C:\Users\Administrator\Documents\R\win-library\4.0\00LOCK\colorspace\libs\x64\colorspace.dll to C:\Users\Administrator\Documents\R\win-library\4.0\colorspace\libs\x64\colorspace.dll: Permission deniedrestored 㤼㸱colorspace㤼㸲
package ‘Rcpp’ successfully unpacked and MD5 sums checked
cannot remove prior installation of package 㤼㸱Rcpp㤼㸲problem copying C:\Users\Administrator\Documents\R\win-library\4.0\00LOCK\Rcpp\libs\x64\Rcpp.dll to C:\Users\Administrator\Documents\R\win-library\4.0\Rcpp\libs\x64\Rcpp.dll: Permission deniedrestored 㤼㸱Rcpp㤼㸲
package ‘cli’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
    C:\Users\Administrator\AppData\Local\Temp\RtmpQZiRta\downloaded_packages
WARNING: Rtools is required to build R packages, but is not currently installed.

Please download and install Rtools 4.0 from https://cran.r-project.org/bin/windows/Rtools/.
  
  
  
√  checking for file 'C:\Users\Administrator\AppData\Local\Temp\RtmpQZiRta\remotesa3c6b60dd8\nikita-moor-ldatuning-1e225c0/DESCRIPTION' (368ms)

  
  
  
-  preparing 'ldatuning':
   checking DESCRIPTION meta-information ...
  
√  checking DESCRIPTION meta-information

  
  
  
-  checking for LF line-endings in source and make files and shell scripts
-  checking for empty or unneeded directories

  
-  building 'ldatuning_1.0.2.tar.gz'

  
   
Installing package into 㤼㸱C:/Users/Administrator/Documents/R/win-library/4.0㤼㸲
(as 㤼㸱lib㤼㸲 is unspecified)
* installing *source* package 'ldatuning' ...
** using staged installation
** R
** demo
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
  converting help for package 'ldatuning'
    finding HTML links ... done
    Arun2010                                html  
Rd warning: C:/Users/Administrator/AppData/Local/Temp/RtmpmMHwap/R.INSTALL3ef4783647b1/ldatuning/man/Arun2010.Rd:10: file link 'LDA' in package 'topicmodels' does not exist and so has been treated as a topic
Rd warning: C:/Users/Administrator/AppData/Local/Temp/RtmpmMHwap/R.INSTALL3ef4783647b1/ldatuning/man/Arun2010.Rd:12: file link 'DocumentTermMatrix' in package 'tm' does not exist and so has been treated as a topic
Rd warning: C:/Users/Administrator/AppData/Local/Temp/RtmpmMHwap/R.INSTALL3ef4783647b1/ldatuning/man/Arun2010.Rd:14: file link 'simple_triplet_matrix' in package 'slam' does not exist and so has been treated as a topic
    CaoJuan2009                             html  
Rd warning: C:/Users/Administrator/AppData/Local/Temp/RtmpmMHwap/R.INSTALL3ef4783647b1/ldatuning/man/CaoJuan2009.Rd:10: file link 'LDA' in package 'topicmodels' does not exist and so has been treated as a topic
    Deveaud2014                             html  
Rd warning: C:/Users/Administrator/AppData/Local/Temp/RtmpmMHwap/R.INSTALL3ef4783647b1/ldatuning/man/Deveaud2014.Rd:10: file link 'LDA' in package 'topicmodels' does not exist and so has been treated as a topic
    FindTopicsNumber                        html  
    finding level-2 HTML links ... done

Rd warning: C:/Users/Administrator/AppData/Local/Temp/RtmpmMHwap/R.INSTALL3ef4783647b1/ldatuning/man/FindTopicsNumber.Rd:20: file link 'DocumentTermMatrix' in package 'tm' does not exist and so has been treated as a topic
Rd warning: C:/Users/Administrator/AppData/Local/Temp/RtmpmMHwap/R.INSTALL3ef4783647b1/ldatuning/man/FindTopicsNumber.Rd:22: file link 'simple_triplet_matrix' in package 'slam' does not exist and so has been treated as a topic
Rd warning: C:/Users/Administrator/AppData/Local/Temp/RtmpmMHwap/R.INSTALL3ef4783647b1/ldatuning/man/FindTopicsNumber.Rd:29: file link 'LDA' in package 'topicmodels' does not exist and so has been treated as a topic
Rd warning: C:/Users/Administrator/AppData/Local/Temp/RtmpmMHwap/R.INSTALL3ef4783647b1/ldatuning/man/FindTopicsNumber.Rd:40: file link 'LDA' in package 'topicmodels' does not exist and so has been treated as a topic
    FindTopicsNumber_plot                   html  
    Griffiths2004                           html  
Rd warning: C:/Users/Administrator/AppData/Local/Temp/RtmpmMHwap/R.INSTALL3ef4783647b1/ldatuning/man/Griffiths2004.Rd:10: file link 'LDA' in package 'topicmodels' does not exist and so has been treated as a topic
    ldatuning                               html  
** building package indices
** installing vignettes
** testing if installed package can be loaded from temporary location
** testing if installed package can be loaded from final location
** testing if installed package keeps a record of temporary installation path
* DONE (ldatuning)
library("ldatuning")


library("topicmodels")
data("AssociatedPress", package="topicmodels")
dtm <- AssociatedPress[1:10, ]


result <- FindTopicsNumber(
  tidy_matrix,
  topics = seq(from = 2, to = 15, by = 1),
  metrics = c("Griffiths2004", "CaoJuan2009", "Arun2010", "Deveaud2014"),
  method = "Gibbs",
  control = list(seed = 77),
  mc.cores = 2L,
  verbose = TRUE
)
fit models... done.
calculate metrics:
  Griffiths2004... done.
  CaoJuan2009... done.
  Arun2010... done.
  Deveaud2014... done.
FindTopicsNumber_plot(result)
`guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> = "none")` instead.

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpXaGF0IHR3ZWV0cyBnb3QgdGhlIG1vc3QgYXR0ZW50aW9uLg0KZnJlcXVlbmN5IG9mIHR3ZWV0cyBwb3N0ZWQgb24gYSB0b3BpYw0KDQoNCmBgYHtyIFNFVFVQfQ0KbGlicmFyeShydHdlZXQpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkodGlkeXRleHQpDQpsaWJyYXJ5KHN0cmluZ3IpDQpsaWJyYXJ5KHNjYWxlcykNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkodmFkZXIpDQpsaWJyYXJ5KHRvcGljbW9kZWxzKQ0KbGlicmFyeShxdWFudGVkYSkNCmxpYnJhcnkobHVicmlkYXRlKQ0KbGlicmFyeSh6b28pDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoZm9yY2F0cykNCmxpYnJhcnkoaWdyYXBoKQ0KbGlicmFyeShnZ3JhcGgpDQpsaWJyYXJ5KHdpZHlyKQ0KbGlicmFyeShxZGFwUmVnZXgpDQoNCm9yaWdvcCA8LSBvcHRpb25zKCJodHRyX29hdXRoX2NhY2hlIikNCm9wdGlvbnMoaHR0cl9vYXV0aF9jYWNoZSA9IFRSVUUpDQoNCmFwaV9rZXkgPC0gIjVQZ3RTN2xqcTVaYkJvWG5lbVU1cUhlNjIiDQphcGlfc2VjcmV0IDwtICJNNDRMZWR1UTR6b3lEeFFJa0FGamVJSnJwRGhXbmI1eEFTRHZoYWhUbHJBdk9oTjdmeCINCmFjY2Vzc190b2tlbiA8LSAiNzQzMDI5NzI0NzUwOTQyMjA4LUpMRXAyNlhyand2UTFDUEpVWHd2ZFVNTGthODJjZ3giDQphY2Nlc3Nfc2VjcmV0IDwtICJYUk1lTUJhT2dReTJCQzFCZDlpSkFSZk1JeUs0MFZLeUlJMVpSY2Y5blMwcWQiDQp0b2tlbiA8LSBjcmVhdGVfdG9rZW4oDQogIGFwcCA9ICJLeWxlUmVzZWFyY2hBcHAiLA0KICBjb25zdW1lcl9rZXkgPSBhcGlfa2V5LA0KICBjb25zdW1lcl9zZWNyZXQgPSBhcGlfc2VjcmV0LA0KICBhY2Nlc3NfdG9rZW4gPSBhY2Nlc3NfdG9rZW4sDQogIGFjY2Vzc19zZWNyZXQgPSBhY2Nlc3Nfc2VjcmV0DQopDQpgYGANCg0KYGBge3IgRmV0Y2hpbmcgVHdlZXRzfQ0KbWVkaWFfYWdlbmN5X2RmIDwtIGdldF90aW1lbGluZSgiTmV3czI0IiwgbiA9IDMyMDApDQptZWRpYV9hZ2VuY3lfZGYgPC0gbWVkaWFfYWdlbmN5X2RmICU+JSANCiAgYmluZF9yb3dzKGdldF90aW1lbGluZSgiZU5DQSIsIG4gPSAzMjAwKSkgJT4lIA0KICBiaW5kX3Jvd3MoZ2V0X3RpbWVsaW5lKCJUaW1lc0xJVkUiLCBuID0gMzIwMCkpICU+JSANCiAgYmluZF9yb3dzKGdldF90aW1lbGluZSgiU0FCQ05ld3MiLCBuID0gMzIwMCkpICU+JSANCiAgYmluZF9yb3dzKGdldF90aW1lbGluZSgiZGFpbHltYXZlcmljayIsIG4gPSAzMjAwKSkNCg0Kd3JpdGVfYXNfY3N2KG1lZGlhX2FnZW5jeV9kZiwgImRhdGFfaW4vbWVkaWFfYWdlbmN5X3R3ZWV0cyIpDQptZWRpYV9hZ2VuY3lfZGYgPC0gcmVhZF9jc3YoImRhdGFfaW4vbWVkaWFfYWdlbmN5X3R3ZWV0cy5jc3YiKQ0KDQptZWRpYV9hZ2VuY3lfZGYgPC0gbWVkaWFfYWdlbmN5X2RmWyAsIGNvbFN1bXMoaXMubmEobWVkaWFfYWdlbmN5X2RmKSkgPCBucm93KG1lZGlhX2FnZW5jeV9kZildDQpgYGANCg0KDQojIENvbXBhcmluZyBUd2VldCBBcmNoaXZlcw0KDQpTb21lIHR3ZWV0cyBmZXRjaGVkIGRhdGUgZnVydGhlciBiYWNrLiBUaGUgMzIwMCB0d2VldCBwdWxsIHBlciB1c2VyIGNhdXNlcyB0aGlzLiBJdCB0ZWxscyB1cyB0aGF0IGFnZW5jaWVzIGxpa2UgTmV3czI0IGFuZCBTQUJDIE5ld3MgVHdlZXQgbW9yZSBkYWlseSB0aGFuIERhaWx5IE1hdmVyaWNrLg0KYGBge3J9DQpnZ3Bsb3QobWVkaWFfYWdlbmN5X2RmLCBhZXMoeCA9IGNyZWF0ZWRfYXQsIGZpbGwgPSBzY3JlZW5fbmFtZSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0ocG9zaXRpb24gPSAiaWRlbnRpdHkiLCBiaW5zID0gMjAsIHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgZmFjZXRfd3JhcCh+c2NyZWVuX25hbWUsIG5jb2wgPSAxKQ0KYGBgDQoNCldlIGZpcnN0IGNsZWFuIHRoZSBvcmlnaW5hbCB0ZXh0IHRvIHJlbW92ZSBsaW5rcywgcHVuY3R1YXRpb24sIGRpZ2l0cywgbGlua3MsIEAncy4NClRoZW4gd2UgdG9rZW5pemUgdGhlIFR3ZWV0cyBhbmQgcmVtb3ZlIHN0b3Agd29yZHMgZnJvbSB0aWR5dGV4dCBhbmQgb3VyIG93biBzdG9wd29yZCBkaWN0aW9uYXJ5LiBXZSBhbHNvIHVzZSB0aGUgInR3aXR0ZXIiIHRva2VuIHRvIGhhbmRsZSBhbnkgbGVmdCBvdmVyIEAncyBhbmQgVVJMUy4NCmBgYHtyIENsZWFuIHVwfQ0KDQojIGNvdmlkX2RpY3Rpb25hcnkgPC0gYygiaGVyZCIsICJpbW11bml0eSIsICJpbmN1YmF0aW9uIiwgImpvYiIsICJsb3NzIiwgIktpdHMiLCAibG9ja2Rvd24iLCAibWFzayIsICJOOTUiLCAib3V0YnJlYWsiLCAicGFuZGVtaWMiLCAicXVhcmFudGluZSIsICJyZWNvdmVyeSIsICJzYW5pdGlzZXIiLCAidHJhbnNtaXNzaW9uIiwgIlVuZGVybHlpbmciLCAiY29uZGl0aW9ucyIsICJWZW50aWxhdG9ycyIsICJXSE8iLCAieGVub3Bob2JpYSIsICJ5b3VUdWJlIiwgInpvb25vdGljIiwgInN0YXktYXQtaG9tZSIsICJjb3ZpZCIsICJjb3JvbmF2aXJ1cyIsICJoeXJkb3h5Y2hsb3JvcXVpbmUiLCAiYXN5bXB0b21hdGljIiwgImZyb250bGluZSIsICJ2aXJ1cyIsICJzZWxmLWlzb2xhdGlvbiIsICJkaXNpbmZlY3RhbnQiLCAic2hlbHRlci1pbi1wbGFjZSIsICJtYXNrcyIsICJTQVJTLUNvVi0yIiwgIklDVSIsICJjb3JvbmEiLCAicmVvcGVuIiwgImRpc3RhbmNpbmciLCAiY292ZXJpbmciLCAiZnVybG91Z2giLCAidHJhY2VyIiwgImVhc2luZyIsICJyZW1kZXNpdmlyIiwgIm1haWwtaW4iLCAiaG9ybmV0IiwgImFudGlib2R5IiwgImluLXBlcnNvbiIsICJkZWZ1bmQiLCAicmFjaXNtIiwgImxvb3RpbmciLCAibG9vdCIsICJyZW9wZW4iLCAidHdvLW1ldHJlIiwgInBhbmRlbWljIiwgImxvb3RlciIsICJkaXN0YW5jaW5nIiwgImRleGFtZXRoYXNvbmUiLCAicmFjaWFsIiwgInZhY2NpbmUiLCAiY3VyZmV3Iiwiam9obnNzb25zIiwgImFzdHJhemVuZWNhIiwgImhvc3BpdGFscyIsICJzb2NpYWwtZGlzdGFuY2UiLCAic29jaWFsLWRpc3RhbmNpbmciLCAicG9saWNlIiwgInJlZ3VsYXRpb25zIiwgInN5bXB0b21zIiwgInRlc3RpbmciLCAicG9zaXRpdmUtdGVzdHMiLCAibmVnYXRpdmUtdGVzdHMiICwgImNvbmZpcm1lZC1jYXNlcyIsICJyZXN0cmljdGlvbnMiLCAiZGVhdGhzIiwgImluZmVjdGVkIiwgInJlY292ZXJpZXMiLCAibGV2ZWwiLCAiam9icyIsICJ1bmVtcGxveWVkIiwgImRvY3RvcnMiLCAiaW5mZWN0aW9ucyIsICJzYW5pdGlzZSIsICJzYW5pdGlzZXIiLCAic2FuaXRpc2F0aW9uIiwgImNvbnRhaW5tZW50IikNCg0KI0pVU1QgdGlkeQ0Kcm1fdHdpdHRlcl9uX3VybCA8LSBybV8ocGF0dGVybj1wYXN0ZXgoIkBybV90d2l0dGVyX3VybCIsICJAcm1fdXJsIikpDQptZWRpYV9hZ2VuY3lfZGYgPC0gbWVkaWFfYWdlbmN5X2RmICU+JSANCiAgbXV0YXRlKHRleHQgPSBybV90d2l0dGVyX25fdXJsKHRleHQpLA0KICAgICAgICAgdGV4dCA9IGdzdWIoIkBcXHcrIiwgIiAiLCB0ZXh0KSwNCiAgICAgICAgIHRleHQgPSBnc3ViKCJbWzpwdW5jdDpdXSIsICIgIiwgdGV4dCksDQogICAgICAgICB0ZXh0ID0gZ3N1YigiW1s6ZGlnaXQ6XV0iLCAiICIsIHRleHQpLA0KICAgICAgICAgdGV4dCA9IGdzdWIoIlsgXHRdezIsfSIsICIgIiwgdGV4dCksDQogICAgICAgICB0ZXh0ID0gZ3N1YigiXlxccyt8XFxzKyQiLCAiICIsIHRleHQpLA0KICAgICAgICAgdGV4dCA9IGdzdWIoIl5cXHMrfFxccyskIiwgIiAiLCB0ZXh0KSwNCiAgICAgICAgIHRleHQgPSBnc3ViKCImYW1wIiwgIiAiLCB0ZXh0KSkgJT4lIA0KICBtdXRhdGUodGV4dCA9IHN0cl9yZXBsYWNlX2FsbCh0ZXh0LCIgIiwiICIpLA0KICAgICAgICAgdGV4dCA9IHN0cl9yZXBsYWNlX2FsbCh0ZXh0LCJSVCBAW2EteixBLVpdKjogIiwiICIpLA0KICAgICAgICAgdGV4dCA9IHN0cl9yZXBsYWNlX2FsbCh0ZXh0LCIjW2EteixBLVpdKiIsIiAiKSwNCiAgICAgICAgIHRleHQgPSBzdHJfcmVwbGFjZV9hbGwodGV4dCwiQFthLXosQS1aXSoiLCIgIikpICANCiMgIGZpbHRlcihzdHJfZGV0ZWN0KHRleHQsIGZpeGVkKGNvdmlkX2RpY3Rpb25hcnksIGlnbm9yZV9jYXNlID0gVFJVRSkpKSANCg0KI21vc3Qgc3RvcCB3b3JkcyBhcmUgZmlsdGVyZWQgYmFzZWQgb24gdGhlIG1lZGlhIGFnZW5jaWVzIHRhZyBhdCB0aGUgYmVnaW5uaW5nIG9mIGVhY2ggVHdlZXQuIGVnLiBXQVRDSDogKmhlYWRsaW5lIGZvbGxvd3MqLg0KYWdlbmN5X3N0b3Bfd29yZHMgPC0gdGliYmxlKHdvcmQgPSBjKCJzYWJjbmV3cyIsICJlbmNhIiwgImRzdHYiLCAic2FiY2t6biIsICJtYXZlcmljayIsICJvcGluaW9uaXN0YSIsICJkbSIsICJzY29ycGlvIiwgImRzdHY0MDMiLCAiaXR1cyIsICJydCIsICJhbXAiLCAidGdpZm9vZCIsICJtYW1lbG9kaSIsICJzdW5kb3ducyIsICJvZm1hZ2F6aW5lYXZhaWxhYmxlIiwgImNhc2FibGFuY2EiLCAib3BlZCIsICJuZXdzZGVjayIsICJlZGl0b3JpYWwiLCAibmV3Zmxhc2giLCAic291dGhhZnJpY2FubW9ybmluZyIsICJuZXdzbGluayIsICJlbmNhcyIsICJzb3V0aGFmcmljYXRvbmlnaHQiLCAidGhlbWlkZGF5dmlldyIsICJ0aGVsZWFkIiwgInByb3BlcnR5bWF0dGVycyIsICJiYSIsICJrYSIsICJ5YSIsICJnYSIsICJ3YSIsICJsZSIsICJrd2EiLCAibW9ybmluZ2xpdmVzYWJjIiwgIm1vbmRheSIsICJwcml4IiwgImF6ZXJiYWlqYW4iLCAiZW5jYXNpcyIsICJlbmNhYnVzaW5lc3MiLCAiZW5jYXNzcGVha3MiLCAic291dGgiLCAiYWZyaWNhIiwgInBtIiwgInNhIiwicG0iLCAiZW5jYXMiLCAiaXNzIiwgImljeW1pIiwgInRpbWVzbGl2ZSIsICJmdWxsdmlldyIsICJuZXdzYnJlYWtzanVsIiwgIm5ld3NicmVha2p1bCIpKSAgDQoNCiN0aWR5IGRmIGFuZCB1bm5lc3QNCnRpZHlfbWVkaWFfZGYgPC0gbWVkaWFfYWdlbmN5X2RmICU+JSANCiAgI2ZpbHRlcihzdHJfZGV0ZWN0KHRleHQsIGZpeGVkKGNvdmlkX2RpY3Rpb25hcnksIGlnbm9yZV9jYXNlID0gVFJVRSkpKSAlPiUNCiAgdW5uZXN0X3Rva2Vucyh3b3JkLCB0ZXh0LCB0b2tlbiA9ICJ0d2VldHMiKSAlPiUgDQogIGZpbHRlcighd29yZCAlaW4lIHN0b3Bfd29yZHMkd29yZCwNCiAgICAgICAgICF3b3JkICVpbiUgYWdlbmN5X3N0b3Bfd29yZHMkd29yZCwNCiAgICAgICAgIyAhd29yZCAlaW4lIG5lZ2F0ZWRfd29yZHMkd29yZDIsDQogICAgICAgICAhd29yZCAlaW4lIHN0cl9yZW1vdmVfYWxsKHN0b3Bfd29yZHMkd29yZCwgIiciKSwNCiAgICAgICAgIHN0cl9kZXRlY3Qod29yZCwgIlthLXpdIikpDQoNCmBgYA0KDQpGcm9tIG91ciB0aWR5ZWQgVHdlZXQgZGF0YXNldCwgd2UgbG9vayBmb3IgdGhlIHRvcCB3b3JkcyB0aGF0IGFwcGVhci4gVGhpcyB3aWxsIGdpdmUgdXMgYSBnb29kIGlkZWEgb2Ygd2hhdCB0b3BpY3MgYXJlIGJlaW5nIGRpc2N1c3NlZCB0aGUgbW9zdC4gV2UgZmluZCB0aGF0IENPVklELTE5IGhhcyBiZWVuIHRoZSBtYWluIHRvcGljIG9mIGRpc2N1c3Npb24uIFByZXNpZGVudCBhcHBlYXJzIHNlY29uZCBhcyBQcmVzaWRlbnQgUmFtYXBob3NhIG9mIFNvdXRoIEFmcmljYSB1c3VhbGx5IGFkcmVzc2VzIHRoZSBuYXRpb24gcmVnYXJkaW5nIENPVklELTE5IGluZm9ybWF0aW9uLiBBZGRpdGlvbmFsbHksIFp1bWEgYWxzbyBhcHBlYXJzIGFzIGhlIGlzIG1lbnRpb25lZCBhcyAiZm9ybWVyIHByZXNpZGVudCBadW1hIiBpbiBtb3N0IGFydGljbGVzLiBadW1hIGFwcGVhcnMgbW9yZSBhcyBoaXMgcmVjZW50IGNvdXJ0IGF2b2lkYW5jZSBhbmQgc2VudGVuY2luZyBpcyBiZWluZyBUd2VldGVkLiBHZW5lcmFsIHdvcmRzIHN1cnJvdW5kaW5nIHRoZSBDT1ZJRC0xOSB0b3BpYyBhcyBpdCBpcyBzdGlsbCB0aGUgbWFpbiBwcmVzc3VyZSBvbiB0aGUgY291bnRyeSwgZXNwaWNpYWxseSBpbnZvbHZpbmcgR2F1dGVuZydzIHJpc2UgaW4gaW5mZWN0aW9ucy4gDQpgYGB7ciB0b3Agd29yZHN9DQojdG9wIHdvcmRzDQp0b3Bfd29yZHMgPC0gdGlkeV9tZWRpYV9kZiAlPiUgDQogIGFudGlfam9pbihzdG9wX3dvcmRzKSAlPiUgDQogIGNvdW50KHdvcmQpICU+JSANCiAgYXJyYW5nZShkZXNjKG4pKQ0KdG9wX3dvcmRzICU+JQ0KICBzbGljZSgxOjIwKSAlPiUNCiAgZ2dwbG90KGFlcyhyZW9yZGVyKHdvcmQsIC1uKSwgbiwgZmlsbCA9IHdvcmQpKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDYwLCBoanVzdCA9IDEsIHNpemUgPSAxMyksDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgc2l6ZSA9IDE4KQ0KICAgICkgKw0KICB5bGFiKCJGcmVxdWVuY3kiKSArDQogIHhsYWIgKCIiKSArDQogIGdndGl0bGUoIk1vc3QgZnJlcXVlbnQgbWVkaWEgYWdlbmN5IHR3ZWV0cyIpICsNCiAgZ3VpZGVzKGZpbGw9RkFMU0UpDQpgYGANCg0KTmV3cw0KYGBge3IgdGYtaWRmIGZyZXF1ZW5jeSBwZXIgYWdlbmN5fQ0KI3RmLWlkZg0KdGlkeV9tZWRpYV90Zl9pZGYgPC0gdGlkeV9tZWRpYV9kZiAlPiUgDQogIHNlbGVjdChzY3JlZW5fbmFtZSwgd29yZCkgJT4lIA0KICBjb3VudCh3b3JkLCBzY3JlZW5fbmFtZSkgJT4lIA0KICBiaW5kX3RmX2lkZih3b3JkLCBzY3JlZW5fbmFtZSwgbikgDQoNCiNjYWxjdWxhdGUgYSBmcmVxdWVuY3kgZm9yIGVhY2ggYWdlbmN5IGFuZCB3b3JkDQpmcmVxdWVuY3kgPC0gdGlkeV9tZWRpYV90Zl9pZGYgJT4lIA0KICBncm91cF9ieShzY3JlZW5fbmFtZSkgJT4lIA0KICBjb3VudCh3b3JkLCBzb3J0ID0gVFJVRSkgJT4lIA0KICBsZWZ0X2pvaW4odGlkeV9tZWRpYV9kZiAlPiUgDQogICAgICAgICAgICAgIGdyb3VwX2J5KHNjcmVlbl9uYW1lKSAlPiUgDQogICAgICAgICAgICAgIHN1bW1hcmlzZSh0b3RhbCA9IG4oKSkpICU+JQ0KICBtdXRhdGUoZnJlcSA9IG4vdG90YWwpDQp0aWR5X21lZGlhX3RmX2lkZiAlPiUgZmlsdGVyKHdvcmQgPT0gImlzcyIpDQp0aWR5X21lZGlhX2RmICU+JSBmaWx0ZXIod29yZCA9PSAiaXNzIikNCg0KdGlkeV9tZWRpYV90Zl9pZGYgJT4lDQogIGdyb3VwX2J5KHNjcmVlbl9uYW1lKSAlPiUNCiAgc2xpY2VfbWF4KHRmX2lkZiwgbiA9IDE1KSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBnZ3Bsb3QoYWVzKHRmX2lkZiwgZmN0X3Jlb3JkZXIod29yZCwgdGZfaWRmKSwgZmlsbCA9IHNjcmVlbl9uYW1lKSkgKw0KICBnZW9tX2NvbChzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGZhY2V0X3dyYXAofnNjcmVlbl9uYW1lLCBuY29sID0gMiwgc2NhbGVzID0gImZyZWUiKSArDQogIGxhYnMoeCA9ICJ0Zi1pZGYiLCB5ID0gTlVMTCkNCmBgYA0KDQpCeSBtb2RlbGxpbmcgYmlncmFtcyBhbmQgdHJpZ3JhbXMgZm9yIG91ciBkYXRhc2V0IGdpdmVzIHVzIGEgYmV0dGVyIHVuZGVyc3RhbmRpbmcgb2Ygd2hhdCB0b3BpYyBpcyBiZWluZyBkaXNjdXNzZWQgd2l0aCBlYWNoIHdvcmQuIFdlIGNhbiB0aGVuIGFsc28gc2VlIHdoaWNoIHNlbnRpbWVudHMgYXJlIGluY29ycmVjdGx5IGxhYmVsZWQuICJub3QgZ29vZCIgZ2l2ZXMgYmV0dGVyIGNvbnRleHQgb2YgYSBuZWdhdGl2ZSBzZW50aW1lbnQsIHJhdGhlciB0aGFuIGl0IGJlaW5nIGluY29ycmVjdGx5IGlkZW50aWZpZWQgYXMgcG9zaXRpdmUgZ29vZC4NCmBgYHtyIGJpZ3JhbXN9DQojYmlncmFtcw0KdGlkeV9iaWdyYW1fZGYgPC0gbWVkaWFfYWdlbmN5X2RmICU+JSANCiAgI2ZpbHRlcihzdHJfZGV0ZWN0KHRleHQsIGZpeGVkKGNvdmlkX2RpY3Rpb25hcnksIGlnbm9yZV9jYXNlID0gVFJVRSkpKSAlPiUNCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KHRleHQsICJeUlQiKSkgJT4lDQogIG11dGF0ZSh0ZXh0ID0gZ3N1YigiID8oZnxodCl0cChzPyk6Ly8oLiopWy5dW2Etel0rIiwgIiAiLCB0ZXh0KSkgJT4lDQogIHVubmVzdF90b2tlbnMoYmlncmFtLCB0ZXh0LCB0b2tlbiA9ICJuZ3JhbXMiLCBuID0gMikgJT4lIA0KICBzZXBhcmF0ZShiaWdyYW0sIGMoIndvcmQxIiwgIndvcmQyIiksIHNlcCA9ICIgIikNCg0KYmlncmFtc19maWx0ZXJlZCA8LSBiaWdyYW1zX3NlcGFyYXRlZCAlPiUNCiAgZmlsdGVyKCF3b3JkMSAlaW4lIHN0b3Bfd29yZHMkd29yZCkgJT4lDQogIGZpbHRlcighd29yZDIgJWluJSBzdG9wX3dvcmRzJHdvcmQpDQoNCiMgbmV3IGJpZ3JhbSBjb3VudHM6DQpiaWdyYW1fY291bnRzIDwtIGJpZ3JhbXNfZmlsdGVyZWQgJT4lIA0KICBjb3VudCh3b3JkMSwgd29yZDIsIHNvcnQgPSBUUlVFKQ0KDQpiaWdyYW1zX3VuaXRlZCA8LSBiaWdyYW1zX2ZpbHRlcmVkICU+JQ0KICB1bml0ZShiaWdyYW0sIHdvcmQxLCB3b3JkMiwgc2VwID0gIiAiKQ0KDQojdGYtaWRmIGJpZ3JhbXMNCmJpZ3JhbV90Zl9pZGYgPC0gYmlncmFtc191bml0ZWQgJT4lDQogIGNvdW50KHNjcmVlbl9uYW1lLCBiaWdyYW0pICU+JQ0KICBiaW5kX3RmX2lkZihiaWdyYW0sIHNjcmVlbl9uYW1lLCBuKSAlPiUNCiAgYXJyYW5nZShkZXNjKHRmX2lkZikpDQoNCmJpZ3JhbV90Zl9pZGYgJT4lDQogIGdyb3VwX2J5KHNjcmVlbl9uYW1lKSAlPiUNCiAgc2xpY2VfbWF4KHRmX2lkZiwgbiA9IDE1KSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBnZ3Bsb3QoYWVzKHRmX2lkZiwgZmN0X3Jlb3JkZXIoYmlncmFtLCB0Zl9pZGYpLCBmaWxsID0gc2NyZWVuX25hbWUpKSArDQogIGdlb21fY29sKHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgZmFjZXRfd3JhcCh+c2NyZWVuX25hbWUsIG5jb2wgPSAyLCBzY2FsZXMgPSAiZnJlZSIpICsNCiAgbGFicyh4ID0gInRmLWlkZiIsIHkgPSBOVUxMKQ0KDQojd2VpZ2h0cyBhbmQgZ3JhcGhzDQpiaWdyYW1fZ3JhcGggPC0gYmlncmFtX2NvdW50cyAlPiUNCiAgZmlsdGVyKG4gPiAxMDApICU+JQ0KICBncmFwaF9mcm9tX2RhdGFfZnJhbWUoKQ0KDQpzZXQuc2VlZCgxMjM0KQ0KYSA8LSBncmlkOjphcnJvdyh0eXBlID0gImNsb3NlZCIsIGxlbmd0aCA9IHVuaXQoLjE1LCAiaW5jaGVzIikpDQpnZ3JhcGgoYmlncmFtX2dyYXBoLCBsYXlvdXQgPSAiZnIiKSArDQogIGdlb21fZWRnZV9saW5rKGFlcyhlZGdlX2FscGhhID0gbiksIHNob3cubGVnZW5kID0gRkFMU0UsDQogICAgICAgICAgICAgICAgIGFycm93ID0gYSwgZW5kX2NhcCA9IGNpcmNsZSguMDcsICdpbmNoZXMnKSkgKw0KICBnZW9tX25vZGVfcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIiwgc2l6ZSA9IDUpICsNCiAgZ2VvbV9ub2RlX3RleHQoYWVzKGxhYmVsID0gbmFtZSksIHZqdXN0ID0gMSwgaGp1c3QgPSAxLCByZXBlbCA9IFRSVUUpICsNCiAgdGhlbWVfdm9pZCgpDQpgYGANCg0KV2UgZ2l2ZSBtb3JlIHdlaWdodCB0byB3b3JkcyB0aGF0IGFwcGVhciBtb3JlIG9mdGVuIHdpdGggdGhlIGluY29ycmVjdCBzZW50aW1lbnQuIFdlIGNhbiBub3cgcmV2ZXJzZSB0aGUgc2VudGltZW50IG9mIHRoZXNlIHdvcmRzIG9uY2UgVkFERVIgaGFzIGJlZW4gcnVuIG9uIHRoZSBkYXRhc2V0Lg0KYGBge3IgbmVnYXRpb24gd29yZHN9DQojdmFkZXIgbGV4aWNvbiBpbXBvcnRlZCBmcm9tIFZBREVSIEdpdEh1YiANCnZhZGVyX2xleGljb24gPC0gcmVhZF9jc3YyKCJkYXRhX2luL3ZhZGVyX2xleGljb24uY3N2IikgJT4lIA0KICByZW5hbWUoIndvcmQiID0gVE9LRU4sICJ2YWx1ZSIgPSBgTUVBTi1TRU5USU1FTlQtUkFUSU5HYCkNCg0KI2NvbW1vbiBuZWdhdGlvbiB3b3Jkcw0KbmVnYXRpb25fd29yZHMgPC0gYygibm90IiwgIm5vIiwgIm5ldmVyIiwgIndpdGhvdXQiLCAibm8iLCAibm90IiwgIm5vbmUiLCAibm8gb25lIiwgIm5vYm9keSIsICJub3RoaW5nIiwgIm5laXRoZXIiLCAibm93aGVyZSIsICJuZXZlciIsICJkb2VzbuKAmXQiLCAiaXNu4oCZdCIsICJ3YXNu4oCZdCIsICJzaG91bGRu4oCZdCIsICJ3b3VsZG7igJl0IiwgImNvdWxkbuKAmXQiLCAid29u4oCZdCIsICJjYW7igJl0IiwgImRvbuKAmXQiKQ0KbmVnYXRlZF93b3JkcyA8LSBiaWdyYW1zX3NlcGFyYXRlZCAlPiUNCiAgZmlsdGVyKHdvcmQxICVpbiUgZml4ZWQobmVnYXRpb25fd29yZHMsIGlnbm9yZV9jYXNlID0gVFJVRSkpICU+JQ0KICBpbm5lcl9qb2luKHZhZGVyX2xleGljb24sIGJ5ID0gYyh3b3JkMiA9ICJ3b3JkIikpICU+JQ0KICBtdXRhdGUodmFsdWUgPSBhcy5kb3VibGUodmFsdWUpKSAlPiUgDQogIGNvdW50KHdvcmQxLCB3b3JkMiwgdmFsdWUsIHNvcnQgPSBUUlVFKSAlPiUgDQogIG11dGF0ZShjb250cmlidXRpb24gPSBuICogdmFsdWUpICU+JQ0KICBhcnJhbmdlKGRlc2MoYWJzKGNvbnRyaWJ1dGlvbikpKSAlPiUNCiAgbXV0YXRlKHdvcmQyID0gcmVvcmRlcih3b3JkMiwgY29udHJpYnV0aW9uKSkNCm5lZ2F0ZWRfd29yZHMgJT4lDQogIGhlYWQoNDApICU+JSANCiAgZ2dwbG90KGFlcyhuICogdmFsdWUsIHdvcmQyLCBmaWxsID0gbiAqIHZhbHVlID4gMCkpICsNCiAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKyANCiAgZmFjZXRfd3JhcCh+d29yZDEsc2NhbGVzID0gImZyZWVfeSIpICsNCiAgbGFicyh4ID0gIlNlbnRpbWVudCB2YWx1ZSAqICMgbnVtYmVyIG9mIG9jY3VycmVuY2VzIiwNCiAgICAgICB5ID0gIldvcmRzIHByZWNlZGVkIGJ5IG5lZ2F0aW9uIHRlcm1zIikNCg0KYGBgDQoNClRyaWdyYW1zIHdlcmUgbW9kZWxsZWQgYnV0IHdlcmUgbm90IG5lY2Vzc2FyeSBhcyBiaWdyYW1zIHByb3ZpZGVkIGVub3VnaCBpbmZvcm1hdGlvbg0KYGBge3IgdHJpZ3JhbXN9DQojdHJpZ3JhbXMNCnRpZHlfdHJpZ3JhbV9kZiA8LSBtZWRpYV9hZ2VuY3lfZGYgJT4lDQogIGZpbHRlcighc3RyX2RldGVjdCh0ZXh0LCAiXlJUIikpICU+JQ0KICBtdXRhdGUodGV4dCA9IGdzdWIoIiA/KGZ8aHQpdHAocz8pOi8vKC4qKVsuXVthLXpdKyIsICIgIiwgdGV4dCkpICU+JQ0KICB1bm5lc3RfdG9rZW5zKHRyaWdyYW0sIHRleHQsIHRva2VuID0gIm5ncmFtcyIsIG4gPSAzKSAlPiUNCiAgc2VwYXJhdGUodHJpZ3JhbSwgYygid29yZDEiLCAid29yZDIiLCAid29yZDMiKSwgc2VwID0gIiAiKQ0KDQp0cmlncmFtc19maWx0ZXJlZCA8LSB0cmlncmFtc19zZXBhcmF0ZWQgJT4lDQogIGZpbHRlcighd29yZDEgJWluJSBzdG9wX3dvcmRzJHdvcmQpICU+JQ0KICBmaWx0ZXIoIXdvcmQyICVpbiUgc3RvcF93b3JkcyR3b3JkKSAlPiUgDQogIGZpbHRlcighd29yZDMgJWluJSBzdG9wX3dvcmRzJHdvcmQpIA0KDQojIG5ldyB0cmlncmFtcyBjb3VudHM6DQp0cmlncmFtX2NvdW50cyA8LSB0cmlncmFtc19maWx0ZXJlZCAlPiUgDQogIGNvdW50KHdvcmQxLCB3b3JkMiwgd29yZDMsIHNvcnQgPSBUUlVFKQ0KDQp0cmlncmFtc191bml0ZWQgPC0gdHJpZ3JhbXNfZmlsdGVyZWQgJT4lDQogIHVuaXRlKHRyaWdyYW0sIHdvcmQxLCB3b3JkMiwgd29yZDMsIHNlcCA9ICIgIikNCg0KI3RmLWlkZiB0cmlncmFtcw0KdGlkeV90cmlncmFtX2RmIDwtIHRyaWdyYW1zX3VuaXRlZCAlPiUNCiAgY291bnQoc2NyZWVuX25hbWUsIHRyaWdyYW0pICU+JQ0KICBiaW5kX3RmX2lkZih0cmlncmFtLCBzY3JlZW5fbmFtZSwgbikgJT4lDQogIGFycmFuZ2UoZGVzYyh0Zl9pZGYpKQ0KDQp0aWR5X3RyaWdyYW1fZGYgJT4lDQogIGdyb3VwX2J5KHNjcmVlbl9uYW1lKSAlPiUNCiAgc2xpY2VfbWF4KHRmX2lkZiwgbiA9IDEwKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBnZ3Bsb3QoYWVzKHRmX2lkZiwgZmN0X3Jlb3JkZXIodHJpZ3JhbSwgdGZfaWRmKSwgZmlsbCA9IHNjcmVlbl9uYW1lKSkgKw0KICBnZW9tX2NvbChzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGZhY2V0X3dyYXAofnNjcmVlbl9uYW1lLCBuY29sID0gMiwgc2NhbGVzID0gImZyZWUiKSArDQogIGxhYnMoeCA9ICJ0Zi1pZGYiLCB5ID0gTlVMTCkNCg0KYGBgDQoNCg0KYGBge3IgQ291bnRpbmcgYW5kIGNvcnJlbGF0aW5nIGFtb25nIHNlY3Rpb25zLCB3YXJuaW5nPUZBTFNFfQ0KbWVkaWFfYWdlbmN5X3NlY3Rpb25fd29yZHMgPC0gbWVkaWFfYWdlbmN5X2RmICU+JQ0KICBtdXRhdGUoc2VjdGlvbiA9IHJvd19udW1iZXIoKSAlLyUgMTApICU+JQ0KICBmaWx0ZXIoc2VjdGlvbiA+IDApICU+JQ0KICB1bm5lc3RfdG9rZW5zKHdvcmQsIHRleHQpICU+JQ0KICBmaWx0ZXIoIXdvcmQgJWluJSBzdG9wX3dvcmRzJHdvcmQpDQoNCiMgY291bnQgd29yZHMgY28tb2NjdXJpbmcgd2l0aGluIHNlY3Rpb25zDQp3b3JkX3BhaXJzIDwtIG1lZGlhX2FnZW5jeV9zZWN0aW9uX3dvcmRzICU+JQ0KICBwYWlyd2lzZV9jb3VudCh3b3JkLCBzZWN0aW9uLCBzb3J0ID0gVFJVRSkNCg0KIyB3ZSBuZWVkIHRvIGZpbHRlciBmb3IgYXQgbGVhc3QgcmVsYXRpdmVseSBjb21tb24gd29yZHMgZmlyc3QNCndvcmRfY29ycyA8LSBtZWRpYV9hZ2VuY3lfc2VjdGlvbl93b3JkcyAlPiUNCiAgZ3JvdXBfYnkod29yZCkgJT4lDQogIGZpbHRlcihuKCkgPj0gMjApICU+JQ0KICBwYWlyd2lzZV9jb3Iod29yZCwgc2VjdGlvbiwgc29ydCA9IFRSVUUpDQoNCiMgQ29ycmVsYXRpb24gb2YgbmV4dCB3b3JkDQojIHdvcmRfY29ycyAlPiUNCiMgICBmaWx0ZXIoaXRlbTEgPT0gInZhY2NpbmUiKQ0KDQp3b3JkX2NvcnMgJT4lDQogIGZpbHRlcihpdGVtMSAlaW4lIGMoImNvdmlkIiwgInZhY2NpbmUiLCAibG9ja2Rvd24iLCAiZ3VhdGVuZyIpKSAlPiUNCiAgZ3JvdXBfYnkoaXRlbTEpICU+JQ0KICBzbGljZV9tYXgoY29ycmVsYXRpb24sIG4gPSA2KSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUoaXRlbTIgPSByZW9yZGVyKGl0ZW0yLCBjb3JyZWxhdGlvbikpICU+JQ0KICBnZ3Bsb3QoYWVzKGl0ZW0yLCBjb3JyZWxhdGlvbikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsNCiAgZmFjZXRfd3JhcCh+IGl0ZW0xLCBzY2FsZXMgPSAiZnJlZSIpICsNCiAgY29vcmRfZmxpcCgpDQoNCnNldC5zZWVkKDEyMzQpDQp3b3JkX2NvcnMgJT4lDQogIGZpbHRlcihjb3JyZWxhdGlvbiA+IC43KSAlPiUNCiAgZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKCkgJT4lDQogIGdncmFwaChsYXlvdXQgPSAiZnIiKSArDQogIGdlb21fZWRnZV9saW5rKGFlcyhlZGdlX2FscGhhID0gY29ycmVsYXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFLCBlZGdlX3dpZHRoID0gMykgKw0KICBnZW9tX25vZGVfcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIiwgc2l6ZSA9IDUpICsNCiAgZ2VvbV9ub2RlX3RleHQoYWVzKGxhYmVsID0gbmFtZSksIHJlcGVsID0gVFJVRSkgKw0KICB0aGVtZV92b2lkKCkNCmBgYA0KDQpgYGB7ciBWQURFUn0NCnZhZGVyX2RmIDwtIHZhZGVyX2RmKG1lZGlhX2FnZW5jeV9kZiR0ZXh0KQ0Kd3JpdGVfYXNfY3N2KHZhZGVyX2RmLCAiZGF0YV9pbi92YWRlciIpDQoNCnZhZGVyX2RmIDwtIHJlYWRfY3N2KCJkYXRhX2luL3ZhZGVyLmNzdiIpDQp2YWRlcl9kZiA8LSB2YWRlcl9kZiAlPiUgbXV0YXRlKCJYMSIgPSByb3dfbnVtYmVyKCkpDQptZWRpYV9hZ2VuY3lfZGYgPC0gbWVkaWFfYWdlbmN5X2RmICU+JSBtdXRhdGUoIlgxIiA9IHJvd19udW1iZXIoKSkNCm1lZGlhX3ZhZGVyX2RmIDwtIG1lZGlhX2FnZW5jeV9kZiAlPiUgbGVmdF9qb2luKHZhZGVyX2RmLCBieSA9ICJYMSIpDQoNCiNzZW50aW1lbnQNCmdncGxvdGx5KGdncGxvdChkYXRhPW1lZGlhX3ZhZGVyX2RmLCBhZXMoeD1jcmVhdGVkX2F0KSkgKw0KICBnZW9tX2xpbmUoYWVzKHk9cm9sbG1lYW4oY29tcG91bmQsIGs9MzAsIG5hLnBhZCA9IFRSVUUpKSwgY29sb3I9InBpbmsiLCBzaXplPS41KSsNCiAgZ2VvbV9zbW9vdGgoYWVzKHk9Y29tcG91bmQpKSArDQogIHRoZW1lX21pbmltYWwoKSsNCiAgZmFjZXRfd3JhcCh+c2NyZWVuX25hbWUpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSkpDQoNCg0KbWVkaWFfdmFkZXJfZGYgJT4lIGZpbHRlcihjb21wb3VuZCAhPSAwKSU+JSBtdXRhdGUoY3JlYXRlZF9hdCA9IGFzLkRhdGUoY3JlYXRlZF9hdCkpICU+JSAgZ3JvdXBfYnkoY3JlYXRlZF9hdCkgJT4lIG11dGF0ZShjb21wb3VuZF9kYWlseSA9IG1lYW4oY29tcG91bmQpLCBwb3NfZGFpbHkgPSBtZWFuKHBvcyksIG5lZ19kYWlseSA9IG1lYW4obmVnKSwgbmV1X2RhaWx5ID0gbWVhbihuZXUpKQ0KDQojTmV3cyBzZW50aW1lbnQgaW5jcmVhc2VkIG92ZXIgdGltZSwgcHJvYmFibHkgYmFzZWQgb24gbGVzcyByZXN0cmljdGlvbnMgYW5kIHZhY2NpbmVzDQptZWRpYV92YWRlcl9kZiAlPiUgZmlsdGVyKGNvbXBvdW5kICE9IDApICU+JSBtdXRhdGUoY3JlYXRlZF9hdCA9IGFzLkRhdGUoY3JlYXRlZF9hdCkpICU+JSAgZ3JvdXBfYnkoY3JlYXRlZF9hdCkgJT4lIG11dGF0ZShjb21wb3VuZF9kYWlseSA9IG1lYW4oY29tcG91bmQpLCBwb3NfZGFpbHkgPSBtZWFuKHBvcyksIG5lZ19kYWlseSA9IG1lYW4obmVnKSwgbmV1X2RhaWx5ID0gbWVhbihuZXUpKSAlPiUgDQogIGdncGxvdChhZXMoY3JlYXRlZF9hdCkpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gY29tcG91bmRfZGFpbHksIGNvbG91ciA9ICJDb21wb3VuZCIpKSArDQogIGdlb21fc21vb3RoKGFlcyh5ID0gY29tcG91bmRfZGFpbHkpLCBmb3JtdWxhID0geSB+IHgpDQoNCiNzZW50aW1lbnQNCmdncGxvdChkYXRhPW1lZGlhX3ZhZGVyX2RmLCBhZXMoeD1jcmVhdGVkX2F0LCBmaWxsID0gc2NyZWVuX25hbWUpKSArDQogIHN0YXRfc21vb3RoKG1lZGlhX3ZhZGVyX2RmICU+JSBmaWx0ZXIoc2NyZWVuX25hbWUgPT0gIk5ld3MyNCIpLCBtYXBwaW5nID0gIGFlcyh5ID0gY29tcG91bmQpKSsNCiAgc3RhdF9zbW9vdGgobWVkaWFfdmFkZXJfZGYgJT4lIGZpbHRlcihzY3JlZW5fbmFtZSA9PSAiZGFpbHltYXZlcmljayIpLCBtYXBwaW5nID0gIGFlcyh5ID0gY29tcG91bmQpKSsNCiAgc3RhdF9zbW9vdGgobWVkaWFfdmFkZXJfZGYgJT4lIGZpbHRlcihzY3JlZW5fbmFtZSA9PSAiZU5DQSIpLCBtYXBwaW5nID0gIGFlcyh5ID0gY29tcG91bmQpKSsNCiAgc3RhdF9zbW9vdGgobWVkaWFfdmFkZXJfZGYgJT4lIGZpbHRlcihzY3JlZW5fbmFtZSA9PSAiU0FCQ05ld3MiKSwgbWFwcGluZyA9ICBhZXMoeSA9IGNvbXBvdW5kKSkrDQogIHN0YXRfc21vb3RoKG1lZGlhX3ZhZGVyX2RmICU+JSBmaWx0ZXIoc2NyZWVuX25hbWUgPT0gIlRpbWVzTElWRSIpLCBtYXBwaW5nID0gIGFlcyh5ID0gY29tcG91bmQpKSsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLDApLCBicmVha3MgPSBjKC0wLjEsIDApKSANCg0KZ2dwbG90KG1lZGlhX3ZhZGVyX2RmICU+JSBhcnJhbmdlKGNvbXBvdW5kKSAlPiUgbXV0YXRlKFgxID0gZmFjdG9yKFgxLCBsZXZlbHMgPSBYMSkpLCBhZXMoeD1YMSkpICsNCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gIGFlcyh5ID0gY29tcG91bmQpKSArDQogIHRoZW1lX21pbmltYWwoKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSkgDQoNCg0KYGBgDQoNCmBgYHtyIEludGVyYWN0aW9uc30NCiMgbWVkaWFfdmFkZXJfZGYgJT4lIHNlbGVjdChmYXZvcml0ZV9jb3VudCwgcmV0d2VldF9jb3VudCkgJT4lIG11dGF0ZShmYXZvcml0ZV9jb3VudCArIHJldHdlZXRfY291bnQpDQoNCm1lZGlhX3ZhZGVyX2RmIDwtIG1lZGlhX3ZhZGVyX2RmICU+JSANCiAgbXV0YXRlKGNyZWF0ZWRfYXQgPSBhcy5EYXRlKGNyZWF0ZWRfYXQpKSAlPiUgIA0KICBncm91cF9ieShjcmVhdGVkX2F0KSAlPiUgDQogIG11dGF0ZShyZXR3ZWV0X2RhaWx5ID0gbWVhbihyZXR3ZWV0X2NvdW50KSwgZmF2b3JpdGVfZGFpbHkgPSBtZWFuKGZhdm9yaXRlX2NvdW50KSwgdG90YWwgPSBtZWFuKGZhdm9yaXRlX2NvdW50ICsgcmV0d2VldF9jb3VudCkpDQojIG1lYW4gZm9yIHRoZSBkYXkNCmdncGxvdGx5KGdncGxvdChkYXRhID0gbWVkaWFfdmFkZXJfZGYsIGFlcyhjcmVhdGVkX2F0KSkgKw0KICBnZW9tX3JpYmJvbihhZXMoeW1pbiA9IDAsIHltYXggPSB0b3RhbCwgZmlsbCA9ICJUb3RhbCIpKSArDQogIGdlb21fcmliYm9uKGFlcyh5bWluID0gMCwgeW1heCA9IGZhdm9yaXRlX2RhaWx5LCBmaWxsID0gIkZhdm9yaXRlcyIpKSArDQogIGdlb21fcmliYm9uKGFlcyh5bWluID0gMCwgeW1heCA9IHJldHdlZXRfZGFpbHksIGZpbGwgPSAiUmV0d2VldHMiKSkgKyANCiAgICB0aGVtZSgNCiAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksDQoNCiAgICAgIGxlZ2VuZC5qdXN0aWZpY2F0aW9uPWMoMCwwKSwNCiAgICAgIGxlZ2VuZC5wb3NpdGlvbj1jKDAsMCksDQogICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksDQoNCiAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCwgZmFjZT0iYm9sZCIsIG1hcmdpbiA9IG1hcmdpbigwLCAwLCAxMCwgMCksIGhqdXN0ID0gMCksDQogICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZCIsIGhqdXN0ID0gMCksDQogICAgKQ0KICAsIHRvb2x0aXAgPSBjKCJ0b3RhbCIsICJmYXZvcml0ZV9kYWlseSIsICJyZXR3ZWV0X2RhaWx5IiwgImNyZWF0ZWRfYXQiKSkNCg0KI3BlYWsgdHdlZXRzDQptZWRpYV92YWRlcl9kZiAlPiUgDQogIGZpbHRlcihjcmVhdGVkX2F0ID09ICIyMDIxLTA1LTAxIiApICU+JSANCiAgc2xpY2VfbWF4KGZhdm9yaXRlX2NvdW50ICsgcmV0d2VldF9jb3VudCkgDQptZWRpYV92YWRlcl9kZiAlPiUgDQogIGZpbHRlcihjcmVhdGVkX2F0ID09ICIyMDIxLTA1LTIzIiApICU+JSANCiAgc2xpY2VfbWF4KGZhdm9yaXRlX2NvdW50ICsgcmV0d2VldF9jb3VudCkgDQoNCm1lZGlhX3ZhZGVyX2RmICU+JSANCiAgIGZpbHRlcihzY3JlZW5fbmFtZSA9PSAiZGFpbHltYXZlcmljayIpICU+JSANCiAgc2xpY2VfbWF4KGZhdm9yaXRlX2NvdW50ICsgcmV0d2VldF9jb3VudCkgDQoNCmNsYXNzKG1lZGlhX3ZhZGVyX2RmJGNyZWF0ZWRfYXQpDQoNCiMgdG9wIHR3ZWV0cw0KIyBlTkNBIENhbGwgZm9yIG1pbmlzdGVycyBvdmVyIDYwIHRvIHJlc2lnbiBodHRwczovL3QuY28vd2xFakpHRXB1aw0KIyBTQ09SUElPXHJcbkZsb3lkIFNoaXZhbWJ14oCZcyBicm90aGVyIHF1aWV0bHkgcGF5cyBiYWNrIFJtIGFkbWl0cyBoZSByZWNlaXZlZCB0aGUgVkJTIG1vbmV5IGdyYXR1aXRvdXNseUxXZU9tTldwDQojIFRpbWVzTElWRQlEbyB5b3UgYXBwcm92ZSBvZiBEdWR1emFuZSBydW5uaW5nIGZvciBwcmVzaWRlbnQ/IGh0dHBzOi8vdC5jby9oQ0RWUUdIUld5DQojIE5ld3MyNCBDb2NhLUNvbGEgbG9zdCAkNCBiaWxsaW9uIGluIG1hcmtldCB2YWx1ZSBhZnRlciBDcmlzdGlhbm8gUm9uYWxkbyBzdWdnZXN0ZWQgcGVvcGxlIGRyaW5rIHdhdGVyIGluc3RlYWQgfCBAQklTb3V0aEFmcmljYQ0KIyBTQUJDTmV3cyBCUkVBS0lORyBORVdTOiBLaW5nIG9mIEVzd2F0aW5pIGhhcyBmbGVkIGFtaWQgcHVibGljIHZpb2xlbmNlIGluIHRoZSBjb3VudHJ5IGh0dHBzOi8vdC5jby8xanY4dlZDdzlkDQpgYGANCg0KYGBge3IgVG9waWMgTW9kZWxsaW5nfQ0KdGlkeV9tYXRyaXggPC0gdGlkeV9tZWRpYV9kZiAlPiUgY291bnQoc2NyZWVuX25hbWUsIHdvcmQpICU+JSBjYXN0X2RmbShzY3JlZW5fbmFtZSwgd29yZCwgbikNCg0KbWVkaWFfbGRhIDwtIExEQSh0aWR5X21hdHJpeCwgayA9IDUsIGNvbnRyb2wgPSBsaXN0KHNlZWQgPSAxMjM0KSkNCg0KbWVkaWFfdG9waWNzIDwtIHRpZHkobWVkaWFfbGRhLCBtYXRyaXggPSAiYmV0YSIpDQoNCm1lZGlhX3RvcF90ZXJtcyA8LSBtZWRpYV90b3BpY3MgJT4lDQogIGdyb3VwX2J5KHRvcGljKSAlPiUNCiAgc2xpY2VfbWF4KGJldGEsIG4gPSAxMCkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIGFycmFuZ2UodG9waWMsIC1iZXRhKQ0KDQptZWRpYV90b3BfdGVybXMgJT4lDQogIG11dGF0ZSh0ZXJtID0gcmVvcmRlcl93aXRoaW4odGVybSwgYmV0YSwgdG9waWMpKSAlPiUNCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IHRlcm0sIG5hbWVzX2Zyb20gPSB0b3BpYywgdmFsdWVzX2Zyb20gPSBiZXRhKSAlPiUNCiAgcmVuYW1lKCJOYXRpb25zIEFkZHJlc3MiID0gMiwgIkdldHRpbmcgdmFjY2luYXRlZCBmb3IgdGhpcmQgd2F2ZSIgPSAzLCAiQW5ub3VuY2VtZW50IG9mIHZhY2NpbmUiID0gNCwgIkNvdmlkLTE5OiBTb3V0aCBBZnJpY2EgdXBkYXRlIiA9IDUsICJWYWNjaW5hdGlvbiBkaXN0cmlidXRpb25zIiA9IDYpICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IGMoMiwzLDQsNSw2KSwgbmFtZXNfdG8gPSAidG9waWMiLCB2YWx1ZXNfdG8gPSAiYmV0YSIpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdncGxvdChhZXMoYmV0YSwgdGVybSwgZmlsbCA9IGZhY3Rvcih0b3BpYykpKSArDQogIGdlb21fY29sKHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgZmFjZXRfd3JhcCh+IHRvcGljLCBzY2FsZXMgPSAiZnJlZSIpICsNCiAgc2NhbGVfeV9yZW9yZGVyZWQoKQ0KYGBgDQoNCmBgYHtyIEdhcCBrIGp1c3RpZnl9DQoNCmluc3RhbGwucGFja2FnZXMoImxkYXR1bmluZyIpDQoNCg0KaW5zdGFsbC5wYWNrYWdlcygiZGV2dG9vbHMiKQ0KZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJuaWtpdGEtbW9vci9sZGF0dW5pbmciKQ0KDQoNCmxpYnJhcnkoImxkYXR1bmluZyIpDQoNCg0KbGlicmFyeSgidG9waWNtb2RlbHMiKQ0KZGF0YSgiQXNzb2NpYXRlZFByZXNzIiwgcGFja2FnZT0idG9waWNtb2RlbHMiKQ0KZHRtIDwtIEFzc29jaWF0ZWRQcmVzc1sxOjEwLCBdDQoNCg0KcmVzdWx0IDwtIEZpbmRUb3BpY3NOdW1iZXIoDQogIHRpZHlfbWF0cml4LA0KICB0b3BpY3MgPSBzZXEoZnJvbSA9IDIsIHRvID0gMTUsIGJ5ID0gMSksDQogIG1ldHJpY3MgPSBjKCJHcmlmZml0aHMyMDA0IiwgIkNhb0p1YW4yMDA5IiwgIkFydW4yMDEwIiwgIkRldmVhdWQyMDE0IiksDQogIG1ldGhvZCA9ICJHaWJicyIsDQogIGNvbnRyb2wgPSBsaXN0KHNlZWQgPSA3NyksDQogIG1jLmNvcmVzID0gMkwsDQogIHZlcmJvc2UgPSBUUlVFDQopDQoNCkZpbmRUb3BpY3NOdW1iZXJfcGxvdChyZXN1bHQpDQpgYGANCg0K